package com.rjkj.medicalwaste.viewmodels

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.alibaba.fastjson.JSONObject
import com.rjkj.medicalwaste.base.BaseViewModel
import com.rjkj.medicalwaste.bean.*
import com.rjkj.medicalwaste.network.response.catchException
import com.rjkj.medicalwaste.network.response.deal
import com.rjkj.medicalwaste.network.response.next
import com.rjkj.medicalwaste.network.retrofit.Api
import com.rjkj.medicalwaste.network.retrofit.baseUrl
import com.rjkj.medicalwaste.repository.UserRepository
import com.rjkj.medicalwaste.utils.AppPrefsUtils
import com.rjkj.medicalwaste.utils.BaseConstant
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.http.Query

class UserViewModel(val userRepository: UserRepository) : BaseViewModel() {
    var cleanerUser = UserBean()
    var setting = MutableLiveData(SettingBean())
    val nurseUser = MutableLiveData<UserBean>()
    val departmentUser = MutableLiveData<UserBean>()
    val stagingRoomUser = MutableLiveData<UserBean>()
    val disposalUser = MutableLiveData<UserBean>()
    val hospitalId = MutableLiveData("")
    val hospitalName = MutableLiveData("")
    val uploadUser = MutableLiveData<UserBean>()
    val changeUrl = MutableLiveData(false)
    suspend fun findUserByQrCode(code: String): UserBean? = userRepository.findUserByCode2(code)
    fun getSerial(): String {
        return setting.value?.serialNum ?: ""
    }

    fun setSerialNum(
        deviceSN: String,
        id: String,
        cardNo: String
    ) {
        viewModelScope.launch {
            request(false) {
                bingEquipmentId(
                    url = getUrl(),
                    cardNo = cardNo,
                    id = id,
                    deviceSN = deviceSN
                )
            }.next {
                if (this.code == 200 && this.data != null) {
                    AppPrefsUtils.putBoolean(BaseConstant.SET_UNIQUE, true)
                    val settingBean = setting.value
                    settingBean!!.id = id
                    settingBean.change = true
                    settingBean.cardNo = cardNo
                    setting.value = (settingBean)
                    userRepository.update(this.data.userAppDTOS)
                } else {
                    tips.value = ("绑定失败")
                }

            }.catchException {
                tips.value = ("绑定失败")
                printStackTrace()
            }

        }
    }

    fun getUrl(): String {
        return setting.value?.url ?: baseUrl
    }

    fun getAllUserData() {
        viewModelScope.launch {
            showLoading()
            request(false) {
                getAllUser(url = getUrl(), getSerial())
            }.next {
                Log.e("TAG", "testRequestData: ${this.data.toString()}")
                this.data?.user?.let {
                    userRepository.update(it)
                }.also {
                    Log.e(TAG, "getAllUserData: $it")
                    tips.value = "已成功拉取数据${it}条"
                }
                closeLoading()
            }.catchException {
                printStackTrace()
                doException(this)
            }
        }
    }

    fun findIPAndPort() {
        viewModelScope.launch {
            request {
                this.findIPAndPort(deviceSN = getSerial())
            }.next {
                if (code == 200 && data != null) {
                    val value = setting.value!!
                    Log.e(TAG, "findIPAndPort: ${data.ip}+${data.port}")
                    if(data.ip.isEmpty()||data.port.isEmpty()){
                        tips.value = "获取失败"
                        return@next
                    }
                    val s = "${data.ip}:${data.port}/"
                    if (value.url != s) {
                        value.url = s
                        changeUrl.value = true
                    }
                    value.change = true
                    setting.value = value
                } else {
                    tips.value = "获取失败"
                    Log.e(TAG, "findIPAndPort: $message")
                }
            }.catchException {
                tips.value = "获取失败"
            }
        }

    }

    suspend fun uploadGarbage(
        garbageBeanList: List<GarbageBean>,
        load: Boolean = false,
        successState: Int,
        failState: Int

    ) {
        val ser = getSerial()
        viewModelScope.launch {
            request(load) {
                for (garbageBean in garbageBeanList) {
                    garbageBean.syncDeviceSN = ser
                }
                uploadData(url = getUrl(), garbageBeanList = garbageBeanList)
            }.next {
                uploadEvent.postValue(false)
                Log.e("data===>", "data=====>${this.data}")
                if (code == 200) {
                    viewModelScope.launch {
                        for (value in garbageBeanList) {
                            val finalState = value.uploadState or successState
                            userRepository.updateState(value.garbageQRCode, finalState)
                        }
                    }
                } else {
                    viewModelScope.launch {
                        for (value in garbageBeanList) {
                            val finalState = value.uploadState or failState
                            userRepository.updateState(value.garbageQRCode, finalState)
                        }
                    }
                }


//                responseText.set(this.data.toString())
            }.catchException {
                uploadEvent.postValue(false)
                viewModelScope.launch {
                    for (value in garbageBeanList) {
                        val finalState = value.uploadState or failState
                        userRepository.updateState(value.garbageQRCode, finalState)
                    }
                }
                printStackTrace()
            }

        }
    }

    fun bindHospital(
        id: String,
        deviceSN: String,
        cardNo: String
    ) {
        viewModelScope.launch {
            request(false) {
                bindHospitalId(
                    url = getUrl(),
                    hospitalId = id,
                    deviceSN = deviceSN,
                    cardNo = cardNo
                )
            }.next {
                if (code == 200&&data!=null) {
                    for (data in data.user) {
                        if (data.hospitalId == id) {
                            AppPrefsUtils.putString(BaseConstant.HOSPITAL_ID, data.hospitalId)
                            AppPrefsUtils.putString(BaseConstant.HOSPITAL_NAME, data.hospitalName)
                            hospitalId.value = data.hospitalId
                            hospitalName.value = data.hospitalName
                            tips.value = "绑定成功"
                            break
                        }
                    }
                    userRepository.update(data.user)
                } else {
                    tips.value = message
                }

            }.catchException {
                tips.value = this.message
                printStackTrace()
            }

        }
    }

    fun checkLogin(code: String): LiveData<UserBean> {
        return userRepository.findUserByCode(code)
    }

    override fun toString(): String {
        return "UserViewModel(nurseUser=${nurseUser.value}, " +
                "departmentUser=${departmentUser.value}," +
                " stagingRoomUser=${stagingRoomUser.value}," +
                " disposalUser=${disposalUser.value}, " +
                "hospitalId=${hospitalId.value})"
    }

    fun departmentClock(value: DepartmentClockReq) {
        viewModelScope.launch {
            request(false) {
                departmentClock(url = getUrl(), req = arrayOf(value))
            }.next {
                if (code != 200) {
                    tips.value = message
                }

            }.catchException {
                printStackTrace()
            }
        }
    }
    suspend fun updateDevice(version: String) : UploadBean? {
        return request(false) {
            updateDevice(
                url = getUrl(),
                version = version,
                deviceSn = getSerial(),)
        }.deal()
    }
    fun sendStackInfo(trace: String) {
        val jsonObject = JSONObject()
        jsonObject["deviceSN"] = getSerial()
        jsonObject["hospitalId"] = hospitalId.value
        jsonObject["errorMessage"] = trace
        viewModelScope.launch {
            request(false) {
                Api.sendStack(jsonObject)
            }.next {
            }.catchException {
                printStackTrace()
            }
        }

    }


}